<?php
declare ( strict_types = 1 )
	;

namespace Initiating\TransactionResources;

use Trance\TransactionGroup;
use UntilDistributed\Log;
use Swoft\Bean\Annotation\Mapping\Bean;
use UntilDistributed\Constant;
use Swoole\Coroutine;

/**
 * 分布式事务资源管理器Transaction类
 * @Bean(scope=Bean::PROTOTYPE)
 */
class TxTransaction extends TransactionHandler {
	
	/**
	 * 
	 * @var unknown
	 */
	private $coroutineId = 0;
	
	public function getCoroutineId(): int {
		return $this->coroutineId;
	}
	
	public function __construct() {
		
		// 初始化swool_client
		$this->initSwooleClient ();
	}
	
	/**
	 * 设置组id
	 *
	 * @param string $groupId        	
	 */
	public function setGroupId(string $groupId): void {
		$this->groupId = $groupId;
	}
	
	/**
	 * 获取事务组信息
	 *
	 * @return TransactionGroup
	 */
	public function getTransGroup(): TransactionGroup {
		return $this->transGroup;
	}
	
	/**
	 * 添加全局事务并设置超时时间
	 *
	 * @param int $timeout        	
	 * @return TransactionGroup|NULL
	 */
	public function addTxGroupAndSetTimeOut(int $timeout = 0): ?TransactionGroup {
		$this->setTimeOut ( $timeout );
		
		return $this->addTxGroup ();
	}
	
	/**
	 * 开启本地事务
	 *
	 * @return [type] [description]
	 */
	public function begin(): bool {
		
		// 添加全局事务
		if ($this->transaction->role == Constant::$txgroup_role_starter) {
			
			return false;
		}
		
		// 发起者开始事务
		return $this->transDb->beginTransaction ();
	}
	
	/**
	 * 回滚
	 */
	public function rollBack(): bool {
		return $this->doRollback ();
	}
	
	/**
	 * 发起者提交全部事务
	 *
	 * @return bool
	 */
	public function submittedByTheInitiator(): bool {
// 		$this->transaction->status = Constant::$tx_status_cancommit;
// 		Log::getInstance ()->info ( "starter: pre-commit start " );
// 		// 发起者commit说明准备阶段都执行成功
// 		// 1.执行precommit
		
// 		$ret_precommit = $this->preCommit ();
		
// 		if (! $ret_precommit) {
// 			Log::getInstance ()->info ( "starter: rollBack start " );
// 			$this->rollBack ();
// 			return false;
// 		}
		// 2.执行commit
		Log::getInstance ()->info ( "starter: doCommit start " );
		return $this->doCommit ();
	}
	
	/**
	 * 事务参与者等待提交指令
	 *
	 * @return [type]
	 */
	public function commit(): bool {
		// 参与者业务执行成功
		$this->transaction->status = Constant::$tx_status_cancommit;
		
		// 注册参与者到全局事务组
		$trans = $this->registTransaction ();
		
		if (! $trans) {
			// 注册失败回滚事务
			$this->localRollback ();
			
			return false;
		}
		
		Log::getInstance ()->info ( 'actor :  wait pre-commit' );
		
		// 同步阻塞等待调用
		$this->waitForReceiveData ();
		return true;
	}
}